package com.taotao.springmvc.init;

import com.taotao.springmvc.ext.TaoTaoController;
import com.taotao.springmvc.ext.TaoTaoRequestMapping;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @Author: wangjin
 * @CreateTime: 2022-08-14  13:53
 */
@Component
public class TaoTaoAbstractHandlerMethodMapping implements ApplicationContextAware, InitializingBean {
    private ApplicationContext applicationContext;

    /**
     * 初始化 url与具体控制类方法 映射
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        //1 从ioc容器获取所有的bean的对象名称
        String[] beanDefinitionNames = this.applicationContext.getBeanDefinitionNames();
        //2 从ioc容器获取到具体的bean对象
        Arrays.stream(beanDefinitionNames).forEach((beanName) -> {
            Object handler = this.applicationContext.getBean(beanName);
            if (handler != null) {
                Class<?> handlerClass = handler.getClass();
                //3.判断类上是否有助解
                TaoTaoController taoControl = handlerClass.getDeclaredAnnotation(TaoTaoController.class);
                if (taoControl != null) {
                    detectHandlerMethods(handler, handlerClass);

                }
            }
        });

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


    private void detectHandlerMethods(Object handler, Class<?> handlerClass) {
        // 4.使用java反射机制获取所有的方法 判断方法上是否有加上MayiktRequestMapping
        Method[] declaredMethods = handlerClass.getDeclaredMethods();
        Arrays.stream(declaredMethods).forEach((method -> {
            //判断方法上是否有加上MayiktRequestMapping
            TaoTaoRequestMapping mayiktRequestMapping = method.getDeclaredAnnotation(TaoTaoRequestMapping.class);
            if (mayiktRequestMapping != null) {
                // 注册url
                // map集合 key url value 控制类、方法
                String reqURL = mayiktRequestMapping.value();
                // 注册存放url
                TaoTaoMappingRegistContainer.getRegistUrl().put(reqURL+".do", new TaoTaoMappingRegistration(handler, method, reqURL));
            }

        }));
    }
}
